﻿using Newtonsoft.Json.Linq;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using X.Core.Interfaces;
using X.Core.Models;

namespace X.Core.Bases
{
    public abstract class DeviceBase : TreeNodeModel, IDevice
    {
        public DeviceBase() : base()
        {
        }

        public virtual (int, string) Refresh(JObject param = null) => (0, null);
        public virtual (int, string) Open(JObject param = null) { IsOpen = true; return (0, null); }
        public virtual (int, string) Close(JObject param = null) { IsOpen = false; return (0, null); }
        public virtual (int, string) TestConnection(JObject param = null) => (0, null);
        public virtual (int, string) GetInfo(out JObject info, JObject param = null) { info = new JObject(); return (0, null); }
        public virtual (int, string) ExecuteCommand(string command, JObject param = null) => (0, null);
        public virtual (int, string, JObject result) ExecuteCommandA(string command, JObject param) { return (0, null, null); }
        public virtual (int, string, JArray result) ExecuteCommandB(string command, JObject param) { return (0, null, null); }

        public virtual Task<(int, string)> OpenAsync(JObject param = null)
        {
            return Task.Run(() =>
            {
                return Open(param);
            });
        }
        public virtual Task<(int, string)> CloseAsync(JObject param = null)
        {
            return Task.Run(() =>
            {
                return Close(param);
            });
        }
        public virtual Task<(int, string)> ExecuteCommandAsync(string command, JObject param = null)
        {
            return Task.Run(() =>
            {
                return ExecuteCommand(command, param);
            });
        }
        public virtual Task<(int, string, JObject result)> ExecuteCommandAAsync(string command, JObject param)
        {
            return Task.Run(() =>
            {
                return ExecuteCommandA(command, param);
            });
        }
        public virtual Task<(int, string, JArray result)> ExecuteCommandBAsync(string command, JObject param)
        {
            return Task.Run(() =>
            {
                return ExecuteCommandB(command, param);
            });
        }

        #region 'Fields'
        int _refreshPeriod;
        bool _isOpen;
        bool _isOffline;
        bool _isDebugModel;
        bool _isBusy;
        bool _isError;
        bool _isStopped;
        bool _isOpening;
        bool _isClosing;
        bool _isClosed;
        bool _isNeedClose;
        bool _isResetting;
        int _refreshCount;
        int _retryPeriod;
        int _retryCount;
        IParameterModel _parameter;
        IDevice _parentDevice;
        IDevice _rootDevice;
        #endregion

        #region 'Properties'
        public int RefreshPeriod { get => _refreshPeriod; set => SetProperty(ref _refreshPeriod, value); }
        public bool IsOpen { get => _isOpen; set => SetProperty(ref _isOpen, value); }
        public bool IsOffline { get => _isOffline; set => SetProperty(ref _isOffline, value); }
        public bool IsDebugModel { get => _isDebugModel; set => SetProperty(ref _isDebugModel, value); }
        public bool IsBusy { get => _isBusy; set => SetProperty(ref _isBusy, value); }
        public bool IsError { get => _isError; set => SetProperty(ref _isError, value); }
        public bool IsStopped { get => _isStopped; set => SetProperty(ref _isStopped, value); }
        public bool IsOpening { get => _isOpening; set => SetProperty(ref _isOpening, value); }
        public bool IsClosing { get => _isClosing; set => SetProperty(ref _isClosing, value); }
        public bool IsClosed { get => _isClosed; set => SetProperty(ref _isClosed, value); }
        public bool IsNeedClose { get => _isNeedClose; set => SetProperty(ref _isNeedClose, value); }
        public bool IsResetting { get => _isResetting; set => SetProperty(ref _isResetting, value); }
        public int RefreshCount { get => _refreshCount; set => SetProperty(ref _refreshCount, value); }
        public int RetryPeriod { get => _retryPeriod; set => SetProperty(ref _retryPeriod, value); }
        public int RetryCount { get => _retryCount; set => SetProperty(ref _retryCount, value); }
        public IParameterModel Parameter { get => _parameter; set => SetProperty(ref _parameter, value); }
        public IDevice ParentDevice { get => _parentDevice; set => SetProperty(ref _parentDevice, value); }
        public IDevice RootDevice { get => _rootDevice; set => SetProperty(ref _rootDevice, value); }
        public ILogger Logger { get; set; }
        public ObservableCollection<IDevice> Devices { get; set; }
        public ObservableCollection<BitDataModel> XDatas { get; set; }
        public ObservableCollection<BitDataModel> YDatas { get; set; }
        public ObservableCollection<UshortDataModel> OutputDatas { get; set; }
        public ObservableCollection<UshortDataModel> InputDatas { get; set; }
        public ObservableCollection<UshortDataModel> ConfigDatas { get; set; }
        public ObservableCollection<ListModel<double>> DDatas { get; set; }
        #endregion

    }
}
